home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Mac Game Programming Gurus / TricksOfTheMacGameProgrammingGurus.iso / More Source / C⁄C++ / Peter's Final Project / jpeg-5b / jdmerge.c < prev    next >
Text File  |  1994-12-08  |  14KB  |  389 lines

  1. /*
  2.  * jdmerge.c
  3.  *
  4.  * Copyright (C) 1994, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains code for merged upsampling/color conversion.
  9.  *
  10.  * This file combines functions from jdsample.c and jdcolor.c;
  11.  * read those files first to understand what's going on.
  12.  *
  13.  * When the chroma components are to be upsampled by simple replication
  14.  * (ie, box filtering), we can save some work in color conversion by
  15.  * calculating all the output pixels corresponding to a pair of chroma
  16.  * samples at one time.  In the conversion equations
  17.  *    R = Y           + K1 * Cr
  18.  *    G = Y + K2 * Cb + K3 * Cr
  19.  *    B = Y + K4 * Cb
  20.  * only the Y term varies among the group of pixels corresponding to a pair
  21.  * of chroma samples, so the rest of the terms can be calculated just once.
  22.  * At typical sampling ratios, this eliminates half or three-quarters of the
  23.  * multiplications needed for color conversion.
  24.  *
  25.  * This file currently provides implementations for the following cases:
  26.  *    YCbCr => RGB color conversion only.
  27.  *    Sampling ratios of 2h1v or 2h2v.
  28.  *    No scaling needed at upsample time.
  29.  *    Corner-aligned (non-CCIR601) sampling alignment.
  30.  * Other special cases could be added, but in most applications these are
  31.  * the only common cases.  (For uncommon cases we fall back on the more
  32.  * general code in jdsample.c and jdcolor.c.)
  33.  */
  34.  
  35. #define JPEG_INTERNALS
  36. #include "jinclude.h"
  37. #include "jpeglib.h"
  38.  
  39. #ifdef UPSAMPLE_MERGING_SUPPORTED
  40.  
  41.  
  42. /* Private subobject */
  43.  
  44. typedef struct {
  45.   struct jpeg_upsampler pub;    /* public fields */
  46.  
  47.   /* Pointer to routine to do actual upsampling/conversion of one row group */
  48.   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
  49.                JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  50.                JSAMPARRAY output_buf));
  51.  
  52.   /* Private state for YCC->RGB conversion */
  53.   int * Cr_r_tab;        /* => table for Cr to R conversion */
  54.   int * Cb_b_tab;        /* => table for Cb to B conversion */
  55.   INT32 * Cr_g_tab;        /* => table for Cr to G conversion */
  56.   INT32 * Cb_g_tab;        /* => table for Cb to G conversion */
  57.  
  58.   /* For 2:1 vertical sampling, we produce two output rows at a time.
  59.    * We need a "spare" row buffer to hold the second output row if the
  60.    * application provides just a one-row buffer; we also use the spare
  61.    * to discard the dummy last row if the image height is odd.
  62.    */
  63.   JSAMPROW spare_row;
  64.   boolean spare_full;        /* T if spare buffer is occupied */
  65.  
  66.   JDIMENSION out_row_width;    /* samples per output row */
  67.   JDIMENSION rows_to_go;    /* counts rows remaining in image */
  68. } my_upsampler;
  69.  
  70. typedef my_upsampler * my_upsample_ptr;
  71.  
  72. #define SCALEBITS    16    /* speediest right-shift on some machines */
  73. #define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
  74. #define FIX(x)        ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  75.  
  76.  
  77. /*
  78.  * Initialize for an upsampling pass.
  79.  */
  80.  
  81. METHODDEF void
  82. start_pass_merged_upsample (j_decompress_ptr cinfo)
  83. {
  84.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  85.   INT32 i, x;
  86.   SHIFT_TEMPS
  87.  
  88.   /* Mark the spare buffer empty */
  89.   upsample->spare_full = FALSE;
  90.   /* Initialize total-height counter for detecting bottom of image */
  91.   upsample->rows_to_go = cinfo->output_height;
  92.  
  93.   /* Initialize the YCC=>RGB conversion tables.
  94.    * This is taken directly from jdcolor.c; see that file for more info.
  95.    */
  96.   upsample->Cr_r_tab = (int *)
  97.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  98.                 (MAXJSAMPLE+1) * SIZEOF(int));
  99.   upsample->Cb_b_tab = (int *)
  100.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  101.                 (MAXJSAMPLE+1) * SIZEOF(int));
  102.   upsample->Cr_g_tab = (INT32 *)
  103.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  104.                 (MAXJSAMPLE+1) * SIZEOF(INT32));
  105.   upsample->Cb_g_tab = (INT32 *)
  106.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  107.                 (MAXJSAMPLE+1) * SIZEOF(INT32));
  108.  
  109.   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
  110.     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  111.     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
  112.     /* Cr=>R value is nearest int to 1.40200 * x */
  113.     upsample->Cr_r_tab[i] = (int)
  114.             RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
  115.     /* Cb=>B value is nearest int to 1.77200 * x */
  116.     upsample->Cb_b_tab[i] = (int)
  117.             RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
  118.     /* Cr=>G value is scaled-up -0.71414 * x */
  119.     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
  120.     /* Cb=>G value is scaled-up -0.34414 * x */
  121.     /* We also add in ONE_HALF so that need not do it in inner loop */
  122.     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
  123.   }
  124. }
  125.  
  126.  
  127. /*
  128.  * Control routine to do upsampling (and color conversion).
  129.  *
  130.  * The control routine just handles the row buffering considerations.
  131.  */
  132.  
  133. METHODDEF void
  134. merged_2v_upsample (j_decompress_ptr cinfo,
  135.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  136.             JDIMENSION in_row_groups_avail,
  137.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  138.             JDIMENSION out_rows_avail)
  139. /* 2:1 vertical sampling case: may need a spare row. */
  140. {
  141.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  142.   JSAMPROW work_ptrs[2];
  143.   JDIMENSION num_rows;        /* number of rows returned to caller */
  144.  
  145.   if (upsample->spare_full) {
  146.     /* If we have a spare row saved from a previous cycle, just return it. */
  147.     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
  148.               1, upsample->out_row_width);
  149.     num_rows = 1;
  150.     upsample->spare_full = FALSE;
  151.   } else {
  152.     /* Figure number of rows to return to caller. */
  153.     num_rows = 2;
  154.     /* Not more than the distance to the end of the image. */
  155.     if (num_rows > upsample->rows_to_go)
  156.       num_rows = upsample->rows_to_go;
  157.     /* And not more than what the client can accept: */
  158.     out_rows_avail -= *out_row_ctr;
  159.     if (num_rows > out_rows_avail)
  160.       num_rows = out_rows_avail;
  161.     /* Create output pointer array for upsampler. */
  162.     work_ptrs[0] = output_buf[*out_row_ctr];
  163.     if (num_rows > 1) {
  164.       work_ptrs[1] = output_buf[*out_row_ctr + 1];
  165.     } else {
  166.       work_ptrs[1] = upsample->spare_row;
  167.       upsample->spare_full = TRUE;
  168.     }
  169.     /* Now do the upsampling. */
  170.     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
  171.   }
  172.  
  173.   /* Adjust counts */
  174.   *out_row_ctr += num_rows;
  175.   upsample->rows_to_go -= num_rows;
  176.   /* When the buffer is emptied, declare this input row group consumed */
  177.   if (! upsample->spare_full)
  178.     (*in_row_group_ctr)++;
  179. }
  180.  
  181.  
  182. METHODDEF void
  183. merged_1v_upsample (j_decompress_ptr cinfo,
  184.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  185.             JDIMENSION in_row_groups_avail,
  186.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  187.             JDIMENSION out_rows_avail)
  188. /* 1:1 vertical sampling case: much easier, never need a spare row. */
  189. {
  190.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  191.  
  192.   /* Just do the upsampling. */
  193.   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
  194.              output_buf + *out_row_ctr);
  195.   /* Adjust counts */
  196.   (*out_row_ctr)++;
  197.   (*in_row_group_ctr)++;
  198. }
  199.  
  200.  
  201. /*
  202.  * These are the routines invoked by the control routines to do
  203.  * the actual upsampling/conversion.  One row group is processed per call.
  204.  *
  205.  * Note: since we may be writing directly into application-supplied buffers,
  206.  * we have to be honest about the output width; we can't assume the buffer
  207.  * has been rounded up to an even width.
  208.  */
  209.  
  210.  
  211. /*
  212.  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
  213.  */
  214.  
  215. METHODDEF void
  216. h2v1_merged_upsample (j_decompress_ptr cinfo,
  217.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  218.               JSAMPARRAY output_buf)
  219. {
  220.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  221.   register int y, cred, cgreen, cblue;
  222.   int cb, cr;
  223.   register JSAMPROW outptr;
  224.   JSAMPROW inptr0, inptr1, inptr2;
  225.   JDIMENSION col;
  226.   /* copy these pointers into registers if possible */
  227.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  228.   int * Crrtab = upsample->Cr_r_tab;
  229.   int * Cbbtab = upsample->Cb_b_tab;
  230.   INT32 * Crgtab = upsample->Cr_g_tab;
  231.   INT32 * Cbgtab = upsample->Cb_g_tab;
  232.   SHIFT_TEMPS
  233.  
  234.   inptr0 = input_buf[0][in_row_group_ctr];
  235.   inptr1 = input_buf[1][in_row_group_ctr];
  236.   inptr2 = input_buf[2][in_row_group_ctr];
  237.   outptr = output_buf[0];
  238.   /* Loop for each pair of output pixels */
  239.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  240.     /* Do the chroma part of the calculation */
  241.     cb = GETJSAMPLE(*inptr1++);
  242.     cr = GETJSAMPLE(*inptr2++);
  243.     cred = Crrtab[cr];
  244.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  245.     cblue = Cbbtab[cb];
  246.     /* Fetch 2 Y values and emit 2 pixels */
  247.     y  = GETJSAMPLE(*inptr0++);
  248.     outptr[RGB_RED] =   range_limit[y + cred];
  249.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  250.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  251.     outptr += RGB_PIXELSIZE;
  252.     y  = GETJSAMPLE(*inptr0++);
  253.     outptr[RGB_RED] =   range_limit[y + cred];
  254.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  255.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  256.     outptr += RGB_PIXELSIZE;
  257.   }
  258.   /* If image width is odd, do the last output column separately */
  259.   if (cinfo->output_width & 1) {
  260.     cb = GETJSAMPLE(*inptr1);
  261.     cr = GETJSAMPLE(*inptr2);
  262.     cred = Crrtab[cr];
  263.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  264.     cblue = Cbbtab[cb];
  265.     y  = GETJSAMPLE(*inptr0);
  266.     outptr[RGB_RED] =   range_limit[y + cred];
  267.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  268.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  269.   }
  270. }
  271.  
  272.  
  273. /*
  274.  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
  275.  */
  276.  
  277. METHODDEF void
  278. h2v2_merged_upsample (j_decompress_ptr cinfo,
  279.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  280.               JSAMPARRAY output_buf)
  281. {
  282.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  283.   register int y, cred, cgreen, cblue;
  284.   int cb, cr;
  285.   register JSAMPROW outptr0, outptr1;
  286.   JSAMPROW inptr00, inptr01, inptr1, inptr2;
  287.   JDIMENSION col;
  288.   /* copy these pointers into registers if possible */
  289.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  290.   int * Crrtab = upsample->Cr_r_tab;
  291.   int * Cbbtab = upsample->Cb_b_tab;
  292.   INT32 * Crgtab = upsample->Cr_g_tab;
  293.   INT32 * Cbgtab = upsample->Cb_g_tab;
  294.   SHIFT_TEMPS
  295.  
  296.   inptr00 = input_buf[0][in_row_group_ctr*2];
  297.   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  298.   inptr1 = input_buf[1][in_row_group_ctr];
  299.   inptr2 = input_buf[2][in_row_group_ctr];
  300.   outptr0 = output_buf[0];
  301.   outptr1 = output_buf[1];
  302.   /* Loop for each group of output pixels */
  303.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  304.     /* Do the chroma part of the calculation */
  305.     cb = GETJSAMPLE(*inptr1++);
  306.     cr = GETJSAMPLE(*inptr2++);
  307.     cred = Crrtab[cr];
  308.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  309.     cblue = Cbbtab[cb];
  310.     /* Fetch 4 Y values and emit 4 pixels */
  311.     y  = GETJSAMPLE(*inptr00++);
  312.     outptr0[RGB_RED] =   range_limit[y + cred];
  313.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  314.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  315.     outptr0 += RGB_PIXELSIZE;
  316.     y  = GETJSAMPLE(*inptr00++);
  317.     outptr0[RGB_RED] =   range_limit[y + cred];
  318.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  319.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  320.     outptr0 += RGB_PIXELSIZE;
  321.     y  = GETJSAMPLE(*inptr01++);
  322.     outptr1[RGB_RED] =   range_limit[y + cred];
  323.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  324.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  325.     outptr1 += RGB_PIXELSIZE;
  326.     y  = GETJSAMPLE(*inptr01++);
  327.     outptr1[RGB_RED] =   range_limit[y + cred];
  328.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  329.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  330.     outptr1 += RGB_PIXELSIZE;
  331.   }
  332.   /* If image width is odd, do the last output column separately */
  333.   if (cinfo->output_width & 1) {
  334.     cb = GETJSAMPLE(*inptr1);
  335.     cr = GETJSAMPLE(*inptr2);
  336.     cred = Crrtab[cr];
  337.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  338.     cblue = Cbbtab[cb];
  339.     y  = GETJSAMPLE(*inptr00);
  340.     outptr0[RGB_RED] =   range_limit[y + cred];
  341.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  342.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  343.     y  = GETJSAMPLE(*inptr01);
  344.     outptr1[RGB_RED] =   range_limit[y + cred];
  345.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  346.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  347.   }
  348. }
  349.  
  350.  
  351. /*
  352.  * Module initialization routine for merged upsampling/color conversion.
  353.  *
  354.  * NB: this is called under the conditions determined by use_merged_upsample()
  355.  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
  356.  * of this module; no safety checks are made here.
  357.  */
  358.  
  359. GLOBAL void
  360. jinit_merged_upsampler (j_decompress_ptr cinfo)
  361. {
  362.   my_upsample_ptr upsample;
  363.  
  364.   upsample = (my_upsample_ptr)
  365.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  366.                 SIZEOF(my_upsampler));
  367.   cinfo->upsample = (struct jpeg_upsampler *) upsample;
  368.   upsample->pub.start_pass = start_pass_merged_upsample;
  369.   upsample->pub.need_context_rows = FALSE;
  370.  
  371.   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
  372.  
  373.   if (cinfo->max_v_samp_factor == 2) {
  374.     upsample->pub.upsample = merged_2v_upsample;
  375.     upsample->upmethod = h2v2_merged_upsample;
  376.     /* Allocate a spare row buffer */
  377.     upsample->spare_row = (JSAMPROW)
  378.       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  379.         (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
  380.   } else {
  381.     upsample->pub.upsample = merged_1v_upsample;
  382.     upsample->upmethod = h2v1_merged_upsample;
  383.     /* No spare row needed */
  384.     upsample->spare_row = NULL;
  385.   }
  386. }
  387.  
  388. #endif /* UPSAMPLE_MERGING_SUPPORTED */
  389.